package com.dullfox.sbm.common.util;

import com.dullfox.sbm.common.bean.TreeModel;
import com.dullfox.sbm.common.bean.TreeModelCheck;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 树结构处理工具类
 */
public class TreeUtil {

	/**
	 * 递归构造有无限层级的树模型
	 * @param parentIdMethodName 获得父Id方法名称
	 * @param tm 树模型
	 * @param o 自关联表的记录
	 * @param li 查询的自关联表的结果集
	 * @param s 往树模型复制的值的方法名称
	 */
	public static void treeBuilder(String parentIdMethodName, TreeModel tm,
								   Object o, List<?> li, String... s) {
		try {
			Class<?> clazz = o.getClass();
			Method pMethod = clazz.getMethod(parentIdMethodName);
			
			for (int i = 0, l = li.size(); i < l; i++) {
				Object parentId = pMethod.invoke(li.get(i));
				if (parentId == null) continue;
				
				if (tm.getId().equals(parentId)) {
					TreeModel ntm = new TreeModel();
					copyModel(ntm, li.get(i), s);// 复制数据到树model
					tm.getChildren().add(ntm);
					treeBuilder(parentIdMethodName, ntm, o, li, s);// 递归
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 复制数据到树model
	 * @param tm 树model
	 * @param o 待复制的对象
	 * @param s 变长参数，方法的名称字符串
	 *          约定第1个为id，第2个为text，
	 *          第3个为linkUrl，第4个为iconCls，
	 *          第5个为splitNum
	 */
	public static void copyModel(TreeModel tm, Object o, String... s) {
		Class<?> clazz = o.getClass();// 获取类包名
		int l = s.length;

		try {
			if(l - 0 > 0 && s[0] != null) {
				Method id = clazz.getMethod(s[0]);// 约定第1个为id
				tm.setId(String.valueOf(id.invoke(o)));
			}
			if(l - 1 > 0 && s[1] != null) {
				Method text = clazz.getMethod(s[1]);// 约定第2个为text
				tm.setText(String.valueOf(text.invoke(o)));
			}
			if(l - 2 > 0 && s[2] != null) {
				Method url = clazz.getMethod(s[2]);// 约定第3个为funcUrl
				Object object = url.invoke(o);
				if (object != null) {
					tm.setLinkUrl(String.valueOf(object));
				}
			}
			if(l - 3 > 0 && s[3] != null) {
				Method cls = clazz.getMethod(s[3]);// 约定第4个为iconCls
				Object object = cls.invoke(o);
				if (object != null) {
					tm.setIconCls(String.valueOf(object));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将普通值集合转换为树json数据
	 * @param li 要转换的java数据值集合
	 * @param s 树结构需要的对应属性的取值方法
	 * @return 返回元素为树数据模型的集合
	 * @throws Exception
	 */
	public static List<TreeModel> listToTree(List<?> li, String... s) {
		List<TreeModel> emList = new ArrayList<TreeModel>();
		try {
			Object o = null; TreeModel em = null;
			for (int i = 0, l = li.size(); i < l; i++) {
				o = li.get(i); em = new TreeModel();
				copyModel(em, o, s); emList.add(em);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return emList;
	}

	/**
	 * 将普通值集合转换为树json数据
	 * 
	 * @param objList
	 *            要转换的java数据值集合
	 * @param getIdMethod
	 *            树结构需要的对应id的取值方法
	 * @param getTextMethod
	 *            树节点名称的对应text的取值方法
	 * @return 返回元素为树数据模型的集合
	 * @throws Exception
	 */
	public static List<TreeModel> listToTree(List<?> objList,
			String getIdMethod, String getTextMethod) {
		List<TreeModel> emList = new ArrayList<TreeModel>();
		try {
			Class<?> clazz = null;
			Method im = null;
			Method tm = null;
			TreeModel em = null;
			for (Object o : objList) {
				em = new TreeModel();
				clazz = o.getClass();

				// 得到获取Id的方法
				im = clazz.getMethod(getIdMethod);
				// 得到获取值的方法
				tm = clazz.getMethod(getTextMethod);

				em.setId(String.valueOf(im.invoke(o)));
				em.setText(String.valueOf(tm.invoke(o)));
				emList.add(em);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return emList;
	}

	/**
	 * 将普通值集合转换为复选树json数据
	 * 
	 * @param objList
	 *            要转换的java数据值集合
	 * @param getIdMethod
	 *            树结构需要的对应id的取值方法
	 * @param getTextMethod
	 *            树节点名称的对应text的取值方法
	 * @param getCheckedMethod
	 *            树节点默认是否选中的取值方法
	 * @return 返回元素为复选树数据模型的集合
	 * @throws Exception
	 */
	public static List<TreeModelCheck> listToCheckTree(List<?> objList,
													   String getIdMethod, String getTextMethod, String getCheckedMethod) {
		List<TreeModelCheck> list = new ArrayList<TreeModelCheck>();
		try {
			Class<?> clazz = null;
			Method im = null, tm = null, cm = null;
			TreeModelCheck em = null;
			
			for (Object o : objList) {
				em = new TreeModelCheck();
				clazz = o.getClass();

				// 得到获取Id的方法
				im = clazz.getMethod(getIdMethod);
				// 得到获取值的方法
				tm = clazz.getMethod(getTextMethod);
				// 得到获取是否选中的方法
				cm = clazz.getMethod(getCheckedMethod);

				em.setId(String.valueOf(im.invoke(o)));
				em.setText(String.valueOf(tm.invoke(o)));
				em.setChecked((Boolean) cm.invoke(o));
				list.add(em);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

}
